package com.maple.common.usbManger;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.util.Log;

import androidx.annotation.NonNull;

import java.util.Collection;

public class UsbDeviceManager {
    private String TAG=this.getClass().getSimpleName();
    public static final String ACTION_USB_PERMISSION = "com.example.usbprinter.permission";
    private static volatile UsbDeviceManager instance;
    private Context mContext;
    private UsbManager mUsbManager;



    private  UsbDevice mUsbDevice;
    private  UsbDeviceConnection mUsbDeviceConnection;
    private UsbInterface mUsbInterface;
    private UsbDeviceCallBack mUsbDeviceCallBack;//数据回调
    private UsbEndpoint mUsbEndpointControl;//控制节点
    private UsbEndpoint mUsbEndpointOutput;//输出节点
    private UsbEndpoint mUsbEndpointInput;//输入节点


    private UsbDeviceManager() {

    }
    /**
     * 获取实例。单例的
     */
    public static UsbDeviceManager getInstance() {
        if (instance == null) {
            synchronized (UsbDeviceManager.class) {
                if (instance == null) {
                    instance = new UsbDeviceManager();
                    instance.printSpeet(5);
                    instance.printConcentration(4);
                }
            }
        }
        return instance;
    }
    public  boolean init(Context context){
        // 获取USB设备
        if (context==null)
            return false;
        mContext=context;
        mUsbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
        if (mUsbManager==null){
            return false;
        }
        startReading();
        return true;

    }
    public void setUsbDeviceCallBack(@NonNull UsbDeviceCallBack mUsbDeviceCallBack) {
        this.mUsbDeviceCallBack = mUsbDeviceCallBack;
    }

    public Collection<UsbDevice> getAllUseDevice(){
        return mUsbManager.getDeviceList().values();
    }

    public boolean hasPermission(UsbDevice device){
       return mUsbManager.hasPermission(device);
    }
    public void requestPermission(UsbDevice device){
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
        mContext.registerReceiver(new UsbActionBroadcastReceiver(mUsbDeviceCallBack), filter);
        PendingIntent mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), 0);
        mUsbManager.requestPermission(device, mPermissionIntent);
    }
    public int openDevice( UsbDevice device) {
        if (device==null){
            return -1;
        }
        if (!mUsbManager.hasPermission(device)) {
            return -2;
        }
        mUsbDeviceConnection = mUsbManager.openDevice(device);
        if (mUsbDeviceConnection == null) {
            return -3;
        }
        if (device.getInterfaceCount() == 0) {
            return -4;
        }
        //首选选择第一个接口
        mUsbInterface = device.getInterface(0);
        if (!mUsbDeviceConnection.claimInterface(mUsbInterface, true)) {
            return -4;
        }
        for (int i = 0; i < mUsbInterface.getEndpointCount(); i++) {
            UsbEndpoint usbEndpoint = mUsbInterface.getEndpoint(i);
            switch (usbEndpoint.getType()) {
                //USB控制传输模式通道
                case UsbConstants.USB_ENDPOINT_XFER_CONTROL:
                    mUsbEndpointControl = usbEndpoint;
                    break;
                //USB块传输模式通道
                case UsbConstants.USB_ENDPOINT_XFER_BULK:
                    //USB中断传输模式通道
                    //   case UsbConstants.USB_ENDPOINT_XFER_INT:
                    switch (usbEndpoint.getDirection()) {
                        case UsbConstants.USB_DIR_OUT:
                            mUsbEndpointOutput = usbEndpoint; //USB块传输模式输出通道
                            break;
                        case UsbConstants.USB_DIR_IN:
                            mUsbEndpointInput = usbEndpoint; //USB块传输模式输入通道
                            break;
                    }
                    break;
            }
        }
        mUsbDevice=device;
        return 0;
    }
    public void close(){
        if (!isConnect()) {
            return;
        }
        try {
            mUsbDeviceConnection.close();
            mUsbDeviceConnection.releaseInterface(mUsbInterface);
            mUsbDeviceConnection = null;
            mUsbEndpointInput = null;
            mUsbEndpointOutput = null;
            mUsbInterface = null;
            Log.d("DemoKit", "Device closed. ");
        } catch (Exception var3) {
            Log.e("DemoKit", "Exception: " + var3.getMessage());
        }
    }
    public boolean isConnect(){
        if (mUsbDevice==null) return false;
        if(mUsbDeviceConnection==null) return false;
        if (mUsbInterface==null) return false;
        if (mUsbEndpointOutput==null) return false;
        if (mUsbEndpointInput==null) return false;
        return true;
    }
    public boolean send(byte[] message){
        if (!isConnect())
            return false;
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }
    public boolean sendPrinterState(){
        if (!isConnect())
            return false;
        byte[] message=new byte[]{0x10,0x04,0x04};
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }
    //走纸
    public boolean sendPrinterStep(){
        if (!isConnect())
            return false;
        byte[] message=new byte[]{0x1B,0X4A,0X60};
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }

    //切刀
    public boolean sendCutter(){
        if (!isConnect())
            return false;
        byte[] message=new byte[]{0x1B,0X69,0X01};
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }



    //学习指令
    public boolean sendStudy(){
        if (!isConnect())
            return false;
        byte[] message=new byte[]{0x1B,0X1B};
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }


    //连续纸
    public boolean pieceToPiece(){
        if (!isConnect())
            return false;
        byte[] message=new byte[]{0x1B,0X01,0x00};
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }
    //设置打印速度
    public boolean printSpeet(int setp){
        if (!isConnect())
            return false;

        byte[] message = new byte[]{0x1D,0X46,0x01};
        switch (setp){
            case 1:
                message=new byte[]{0x1D,0X46,0x01};
                break;
            case 2:
                message=new byte[]{0x1D,0X46,0x02};
                break;
            case 3:
                message=new byte[]{0x1D,0X46,0x03};
                break;
            case 4:
                message=new byte[]{0x1D,0X46,0x04};
                break;
            case 5:
                message=new byte[]{0x1D,0X46,0x05};
                break;

        }
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }
    //设置打印对齐方式
    public boolean setAlignment(int setp){
        if (!isConnect())
            return false;

        byte[] message = new byte[]{0x1b,0X61,0x00};
        switch (setp){
            case 1:
                //居左打印
                message=new byte[]{0x1b,0X61,0x00};
                break;
            case 2:
                //居中打印
                message=new byte[]{0x1b,0X61,0x01};
                break;
            case 3:
                //居右打印
                message=new byte[]{0x1b,0X61,0x02};
                break;

        }
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }
    //设置打印浓度
    public boolean printConcentration(int setp){
        if (!isConnect())
            return false;

        byte[] message = new byte[]{0x1D,0X47,0x01};
        switch (setp){
            case 1:
                message=new byte[]{0x1D,0X47,0x01};
                break;
            case 2:
                message=new byte[]{0x1D,0X47,0x02};
                break;
            case 3:
                message=new byte[]{0x1D,0X47,0x03};
                break;
            case 4:
                message=new byte[]{0x1D,0X47,0x04};
                break;
            case 5:
                message=new byte[]{0x1D,0X47,0x05};
                break;

        }
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }
    //标签纸每张切
    public boolean cutPer(){
        if (!isConnect())
            return false;
        byte[] message=new byte[]{0x1B,0X01,0x01};
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }

    //标签纸末尾切
    public boolean cutInEnd(){
        if (!isConnect())
            return false;
        byte[] message=new byte[]{0x1B,0X01,0x02};
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }

    //黑标纸
    public boolean black_(){
        if (!isConnect())
            return false;
        byte[] message=new byte[]{0x1B,0X01,0x03};
        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOutput, message, message.length, 1000);
        return true;
    }





    //开线程读取数据
    public void startReading() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (this) {
                        if (!isConnect()) {

                            continue;
                        }
                        //创建接收数据的数组
                        byte[] data = new byte[mUsbEndpointInput.getMaxPacketSize()];
                        //读取数据
                        int ret = mUsbDeviceConnection.bulkTransfer(mUsbEndpointInput, data, data.length, 1000);
                        if (ret>0){
                            if (mUsbDeviceCallBack!=null);
                                mUsbDeviceCallBack.onReceive(data,ret);
                        }

                    }
                }
            }
        }).start();
    }
    public UsbDevice getUsbDevice() {
        return mUsbDevice;
    }

    public void setUsbDevice(UsbDevice mUsbDevice) {
        this.mUsbDevice = mUsbDevice;
    }
}
